package controllers;

import java.util.ArrayList;
import java.util.List;

import models.Community;
import models.Entities;
import models.Organization;
import models.Permission;
import models.Relation;
import models.SearchResults;
import models.Tag;
import models.Topic;
import models.User;
import play.data.validation.Required;
import play.mvc.Controller;

/**
 * This controller is created for the advanced Search
 * 
 * @author Nourhan El-Nehlawy
 * 
 */
public class AdvancedSearch extends Controller {

	/**
	 * This method renders a page to search for relations whether by name or by
	 * specifying source and destination
	 * 
	 * @author Nourhan El-Nehlawy
	 */

	public static void advancedSearch() {
		render();
	}

	/**
	 * This method takes input from the user, which is the search relationName
	 * and renders a page with the results
	 * 
	 * @param search
	 *            it is the search input which is the relation Name
	 * @param page
	 *            it is the number of page that the user would choose
	 * 
	 * @author Nourhan El-Nehlawy
	 */

	public static void searchForRelationNames(
			@Required(message = "You should enter something to search for") String search,
			Integer page) {
		if (validation.hasErrors()) {
			validation.keep();
			advancedSearch();
		}

		if (page == null)
			page = (int) 1;
		SearchResults results = Relation.searchForRelationsName(search, page);

		List<Relation> relationListBefore = results.items;

		String idString = session.get("userId");
		Long idOne = Long.parseLong(idString);
		User user = User.findById(idOne);

		List<Relation> relationList = new ArrayList<Relation>();
		if (!relationListBefore.isEmpty()) {
			for (int i = 0; i < relationListBefore.size(); i++) {
				Relation relation = relationListBefore.get(i);

				if (relation.checkType(idOne)) {
					System.out.println(relation.organization.type);
					relationList.add(relation);
				}
			}
		}

		int length = relationList.size();

		render(results, relationList, page, search, length);
	}

	/**
	 * This method takes input from the user, which is the search relationName,
	 * source and destination and renders a page with the results
	 * 
	 * @param relatioName
	 *            name of the relation chosen from the drop down list
	 * @param page
	 *            it is the number of page that the user would choose
	 * @author Nourhan El-Nehlawy
	 */
	public static void searchForRelationsSourceDestinationEntity(
			@Required String relationName, Integer page) {
		String source = params.get("search1");
		// String relationName = params.get("search2");
		String destination = params.get("search3");

		// if(source.isEmpty())

		if (validation.hasErrors()) {
			flash.error("Please select values from the box!");
			AdvancedSearch.chooseEntityRelation();
		}

		if (page == null)
			page = 1;
		SearchResults results = Relation
				.searchForRelationsSourceDestinationEntity(source,
						relationName, destination, page, "entity");
		List<Relation> relationListBefore = results.items;

		String idString = session.get("userId");
		Long idOne = Long.parseLong(idString);
		User user = User.findById(idOne);

		List<Relation> relationList = new ArrayList<Relation>();
		if (!relationListBefore.isEmpty()) {
			for (int i = 0; i < relationListBefore.size(); i++) {
				Relation relation = relationListBefore.get(i);

				if (relation.checkType(idOne)) {
					System.out.println(relation.organization.type);
					relationList.add(relation);
				}
			}
		}
		render(results, relationList, source, relationName, destination, page);

	}

	/**
	 * This method takes input from the user, which is the search relationName,
	 * source and destination and renders a page with the results
	 * 
	 * @param page
	 *            it is the number of page that the user would choose
	 * @author Nourhan El-Nehlawy
	 */
	public static void searchForRelationsSourceDestinationTopic(
			@Required String relationName, Integer page) {
		String source = params.get("search1");
		// String relationName = params.get("search2");
		String destination = params.get("search3");

		// if(source.isEmpty())

		if (validation.hasErrors()) {
			flash.error("Please select values from the box!");
			AdvancedSearch.chooseTopicRelation();
		}

		if (page == null)
			page = 1;
		SearchResults results = Relation
				.searchForRelationsSourceDestinationTopic(source, relationName,
						destination, page, "topic");
		List<Relation> relationListBefore = results.items;

		String idString = session.get("userId");
		Long idOne = Long.parseLong(idString);
		User user = User.findById(idOne);

		List<Relation> relationList = new ArrayList<Relation>();
		if (!relationListBefore.isEmpty()) {
			for (int i = 0; i < relationListBefore.size(); i++) {
				Relation relation = relationListBefore.get(i);

				if (relation.checkType(idOne)) {
					System.out.println(relation.organization.type);
					relationList.add(relation);
				}
			}
		}
		render(results, relationList, source, relationName, destination, page);

	}

	/**
	 * This method takes input from the user, which is the search relationName,
	 * source and destination and renders a page with the results
	 * 
	 * @param page
	 *            it is the number of page that the user would choose
	 * @author Nourhan El-Nehlawy
	 */
	public static void searchForRelationsSourceDestinationTag(
			@Required String relationName, Integer page) {
		String source = params.get("search1");
		// String relationName = params.get("search2");
		String destination = params.get("search3");

		if (validation.hasErrors()) {
			flash.error("Please select values from the box!");
			AdvancedSearch.chooseTagRelation();
		}

		if (page == null)
			page = 1;
		SearchResults results = Relation
				.searchForRelationsSourceDestinationTag(source, relationName,
						destination, page, "tag");
		List<Relation> relationListBefore = results.items;

		String idString = session.get("userId");
		Long idOne = Long.parseLong(idString);
		User user = User.findById(idOne);

		List<Relation> relationList = new ArrayList<Relation>();
		if (!relationListBefore.isEmpty()) {
			for (int i = 0; i < relationListBefore.size(); i++) {
				Relation relation = relationListBefore.get(i);

				if (relation.checkType(idOne)) {
					System.out.println(relation.organization.type);
					relationList.add(relation);
				}
			}
		}
		render(results, relationList, source, relationName, destination, page);

	}

	/**
	 * This method takes the id of relation as an input, when the user clicks on
	 * the relation search result and renders the profile of the relation
	 * 
	 * @param id
	 *            it is the id of the relation result
	 * @author Nourhan El-Nehlawy
	 */
	public static void showSearchRelation(Long id) {
		Relation RelationRes = Relation.findById(id);
		render(RelationRes);

	}

	/**
	 * This method takes the id of relation as an input, when the user clicks on
	 * the source Entity search result and renders the profile of the Entity
	 * 
	 * @param id
	 *            it is the id of the relation result
	 * @author Nourhan El-Nehlawy
	 */
	public static void showSourceEntity(Long id) {
		Relation relation = Relation.findById(id);
	
		Entities entity = relation.entityList.get(0);
		// render(entity);

		Organization entityOrganization = entity.organization;
		String idstring = session.get("userId");
		Long id1 = Long.parseLong(idstring);
		User user = User.findById(id1);

		boolean userEntry = entityOrganization.checkUser(user);
		if (userEntry) {
			boolean inSubscriber = entity.userinSubscribers(user);
			List<User> alluser = entity.getSubscribers();

			boolean permit = true;
			boolean authorized = false;
			Permission permissionRole = User.userPermissionInOrganization(
					user.id, entityOrganization.id);
			String role = permissionRole.aUserType;

			Permission permissionUserType = User.userPermissionInOrganization(
					id1, entityOrganization.id);
			String userType = permissionUserType.aUserType;
			if (userType.matches("organizationLead")
					|| userType.matches("organizer")) {
				authorized = true;
			}

			else {
				authorized = false;
			}

			render(relation,userEntry, entity, inSubscriber, alluser, permit,
					entityOrganization, authorized, user, role);
		
		} else
			render(relation, userEntry, entityOrganization);
	
	}

	/**
	 * This method takes the id of relation as an input, when the user clicks on
	 * the destination Entity search result and renders the profile of the
	 * Entity
	 * 
	 * @param id
	 *            it is the id of the relation result
	 * @author Nourhan El-Nehlawy
	 */
	public static void showDestinationEntity(Long id) {
		Relation relation = Relation.findById(id);
		Entities entity = relation.entityList.get(1);

		Organization entityOrganization = entity.organization;
		String idstring = session.get("userId");
		Long id1 = Long.parseLong(idstring);
		User user = User.findById(id1);

		boolean userEntry = entityOrganization.checkUser(user);
		if (userEntry) {
			boolean inSubscriber = entity.userinSubscribers(user);
			List<User> alluser = entity.getSubscribers();

			boolean permit = true;
			boolean authorized = false;
			Permission permissionRole = User.userPermissionInOrganization(
					user.id, entityOrganization.id);
			String role = permissionRole.aUserType;

			Permission permissionUserType = User.userPermissionInOrganization(
					id1, entityOrganization.id);
			String userType = permissionUserType.aUserType;
			if (userType.matches("organizationLead")
					|| userType.matches("organizer")) {
				authorized = true;
			}

			else {
				authorized = false;
			}

			render(userEntry, entity, inSubscriber, alluser, permit,
					entityOrganization, authorized, user, role);
		} else
			render(userEntry, entityOrganization);
	}

	/**
	 * This method takes the id of relation as an input, when the user clicks on
	 * the source Topic search result and renders the profile of the Topic
	 * 
	 * @param id
	 *            it is the id of the relation result
	 * @author Nourhan El-Nehlawy
	 */

	public static void showSourceTopic(Long id) {
		String userId = session.get("userId");
		Long user1 = Long.parseLong(userId);
		User user = User.findById(user1);

		Relation relation = Relation.findById(id);
		Topic topic = relation.topicList.get(0);

		Entities entity = topic.entity;
		Organization topicOrganization = entity.organization;

		boolean userEntry = topicOrganization.checkUser(user);
		if (userEntry) {
			boolean inSubscriber = topic.userinSubscribers(user);
			topic.save();

			List<User> entityOrganizer = entity.entityOrganizers;

			boolean authorized = false;

			if (topicOrganization.lead == user) {
				authorized = true;
			} else {
				for (int i = 0; i < entityOrganizer.size(); i++) {

					if (entityOrganizer.get(i) == user) {
						authorized = true;
					} else {
						authorized = false;
					}

				}
			}

			render(userEntry, topicOrganization, topic, user, authorized,
					inSubscriber);
		} else
			render(userEntry, topicOrganization);
	}

	/**
	 * This method takes the id of relation as an input, when the user clicks on
	 * the destination Topic search result and renders the profile of the Topic
	 * 
	 * @param id
	 *            it is the id of the relation result
	 * @author Nourhan El-Nehlawy
	 */
	public static void showDestinationTopic(Long id) {
		String userId = session.get("userId");
		Long user1 = Long.parseLong(userId);
		User user = User.findById(user1);

		Relation relation = Relation.findById(id);
		Topic topic = relation.topicList.get(1);
		Entities entity = topic.entity;
		Organization topicOrganization = entity.organization;

		boolean userEntry = topicOrganization.checkUser(user);
		if (userEntry) {
			boolean inSubscriber = topic.userinSubscribers(user);
			topic.save();

			List<User> entityOrganizer = entity.entityOrganizers;

			boolean authorized = false;

			if (topicOrganization.lead == user) {
				authorized = true;
			} else {
				for (int i = 0; i < entityOrganizer.size(); i++) {

					if (entityOrganizer.get(i) == user) {
						authorized = true;
					} else {
						authorized = false;
					}

				}
			}

			render(userEntry, topicOrganization, topic, user, authorized,
					inSubscriber);
		} else
			render(userEntry, topicOrganization);
	}

	/**
	 * This method takes the id of relation as an input, when the user clicks on
	 * the source Tag search result and renders the profile of the tag
	 * 
	 * @param id
	 *            it is the id of the relation result
	 * @author Nourhan El-Nehlawy
	 */
	public static void showSourceTag(Long id) {
		String userId = session.get("userId");
		Long user1 = Long.parseLong(userId);
		User user = User.findById(user1);

		Relation relation = Relation.findById(id);
		Tag tag = relation.tagList.get(0);

		Organization tagOrganization = tag.organization;

		boolean userEntry = tagOrganization.checkUser(user);
		if (userEntry) {

			boolean inSubscriber = tag.userinSubscribers(user);
			tag.save();

			render(tag, inSubscriber, userEntry, tagOrganization);
		} else
			render(userEntry, tagOrganization);
	}

	/**
	 * This method takes the id of relation as an input, when the user clicks on
	 * the dstination Tag search result and renders the profile of the tag
	 * 
	 * @param id
	 *            it is the id of the relation result
	 * @author Nourhan El-Nehlawy
	 */
	public static void showDestinationTag(Long id) {
		String userId = session.get("userId");
		Long user1 = Long.parseLong(userId);
		User user = User.findById(user1);

		Relation relation = Relation.findById(id);
		Tag tag = relation.tagList.get(1);

		Organization tagOrganization = tag.organization;

		boolean userEntry = tagOrganization.checkUser(user);
		if (userEntry) {
			boolean inSubscriber = tag.userinSubscribers(user);
			tag.save();

			render(tag, inSubscriber, userEntry, tagOrganization);
		} else
			render(userEntry, tagOrganization);

	}

	/**
	 * This method renders a list of relations related to the all entities
	 * 
	 * @author Nourhan El-Nehlawy
	 */
	public static void chooseEntityRelation() {
		List<Relation> entityRelationList = Relation.chooseEntityRelation();
		render(entityRelationList);
	}

	/**
	 * This method renders a list of relations related to the all topics
	 * 
	 * @author Nourhan El-Nehlawy
	 */
	public static void chooseTopicRelation() {
		List<Relation> topicRelationList = Relation.chooseTopicRelation();
		render(topicRelationList);
	}

	/**
	 * This method renders a list of relations related to the all tags
	 * 
	 * @author Nourhan El-Nehlawy
	 */
	public static void chooseTagRelation() {
		List<Relation> tagRelationList = Relation.chooseTagRelation();
		render(tagRelationList);
	}

	/**
	 * renders a page for the advanced search options
	 * 
	 * @author Mohamed Abdel Kader
	 */

	public static void searchHome() {
		render();
	}

}
